package no.progark.golf.views;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;

import no.progark.golf.Ball;
import no.progark.golf.Golf;
import no.progark.golf.Map;
import no.progark.golf.PointCalculator;
import no.progark.golf.Wall;
import no.progark.golf.activities.GameSettingsActivity;
import no.progark.golf.controller.MenuBarController;
import no.progark.logic.Logic;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class TestView extends View implements PropertyChangeListener, android.view.GestureDetector.OnGestureListener {
	private GestureDetector detector;
	private Canvas canvas;
	private Bitmap background;
	private Bitmap scaledBackground;
	public static ArrayList<float[]> lineCoords;
	public static ArrayList<Wall> lineSegs;
	private Ball ball;

	private MotionEvent ballpressedevent;
	private boolean first = true;
	private static MotionEvent up;
	private static MotionEvent down;
	private static boolean ballpressed;
	public static boolean pressed;
	
	public long prevMS = System.currentTimeMillis(); //Time of last draw
	public long currentMS = 0; //Current time difference from last draw
	public long second = 0; //Times one second, used for calculating frames per second.
	public int oldFPS = 0; // The one that is painted
	public int currentFPS = 0; //We calculate this untill a second has passed, then set value to old. paint old value for One whole second.
	public long dt = 0;
	
	private Paint globalPaint = new Paint();
	
	
	private Golf game = Golf.getInstance();
	
	boolean newLine = false;
	

	public TestView(Context context) {
		super(context);
		detector = new GestureDetector(this);
		background = BitmapFactory.decodeResource(getResources(), game.getCurrentMap().getImage());
		lineCoords = new ArrayList<float[]>();
		lineSegs = new ArrayList<Wall>();
		game.nextPlayer();
		globalPaint.setColor(Color.LTGRAY);
		Golf.addPropertyChangeListener(this);
		// TODO Auto-generated constructor stub
	}
	
	public TestView(Context context, AttributeSet attrs) {
		super( context, attrs );
		detector = new GestureDetector(this);
		background = BitmapFactory.decodeResource(getResources(), game.getCurrentMap().getImage());
		lineCoords = new ArrayList<float[]>();
		lineSegs = new ArrayList<Wall>();
		game.nextPlayer();
		globalPaint.setColor(Color.LTGRAY);
		Golf.addPropertyChangeListener(this);
	}
		
	public TestView(Context context, AttributeSet attrs, int defStyle) {
			super( context, attrs, defStyle );
			detector = new GestureDetector(this);
			background = BitmapFactory.decodeResource(getResources(), game.getCurrentMap().getImage());
			lineCoords = new ArrayList<float[]>();
			lineSegs = new ArrayList<Wall>();
			game.nextPlayer();
			globalPaint.setColor(Color.LTGRAY);
			Golf.addPropertyChangeListener(this);
	}
		 
	@Override
	public void onDraw(Canvas c) {
		this.canvas = c; 
		super.onDraw(this.canvas);
		
		
		if(first && !game.gameFinished){
			game.setCanvasHeight(canvas.getHeight());
			game.setCanvasWidth(canvas.getWidth());
			ball = game.getCurrentPlayer().getBall();
			scaledBackground = getResizedBitmap(background, canvas.getHeight(), canvas.getWidth());
			Map.setStartPos(scaledBackground);
			game.initBallPositions(getContext());
			first = false;
		}
		
		if(!game.gameFinished){ 
			ball = game.getCurrentPlayer().getBall();
		}

		
		canvas.drawBitmap(scaledBackground,0,0,null);
		if(game.gameFinished){
			game.printWinner(c);
		}

		if(!lineCoords.isEmpty())drawLines(c);
		 
		if(!MenuBarController.isWallButtonEnabled()){
			if (ballpressed) {
				ball.drawPowerLine(c, ballpressedevent);  
			}
		}
		
		if(MenuBarController.isWallButtonEnabled()){
			if(up!= null){ 
				drawLine(canvas);
			}
		}
		
		calcFPS();
//		drawFPS(oldFPS, 20, 50, c);
		
		if(!game.gameFinished) ball.update(c,lineSegs, scaledBackground);
		showPlayerTurn(c);
		invalidate(); 
	}
	
	public void drawLine(Canvas c){
		Paint paint = new Paint();
		paint.setColor(Color.GREEN);
		paint.setStrokeWidth(3);
		paint.setStyle(Paint.Style.STROKE);
		float[] coords = Logic.computeMaxWall(down.getX(), down.getY(), up.getX(), up.getY());
		if (lineSegs.size()<=2) {
			if(!MenuBarController.getSettingsButton().isPressed() ){
				canvas.drawLine(down.getX(), down.getY(), coords[0],coords[1], paint);
			}
			if(!pressed && newLine){
				Wall seg = new Wall(down.getX(), down.getY(), coords[0],coords[1]);
				lineSegs.add(seg);
				float[] temp = {down.getX(), down.getY(), coords[0],coords[1]};
				newLine = false;
				lineCoords.add(temp);
			}
		}		
	}
	
	

	private void drawLines(Canvas c) {
		Paint paint = new Paint();
		paint.setColor(Color.GREEN);
		paint.setStrokeWidth(3);
		paint.setStyle(Paint.Style.STROKE);
		for (int i = 0; i < lineCoords.size(); i++) {
			c.drawLine(lineCoords.get(i)[0], lineCoords.get(i)[1], lineCoords.get(i)[2], lineCoords.get(i)[3], paint);
		}
		
	} 

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if(event.getX() > ball.getMiddleX()-(ball.getImage().getWidth()) && event.getX() < ball.getMiddleX()+(ball.getImage().getWidth())){
			if(event.getY() > ball.getMiddleY()-(ball.getImage().getHeight()) && event.getY() < ball.getMiddleY()+(ball.getImage().getHeight())){
				if(!ballpressed && event.getAction() == MotionEvent.ACTION_DOWN && !MenuBarController.isWallButtonEnabled()){
					ballpressed = true;
					ballpressedevent = event;
				}
			}
		}
		if(event.getAction() == MotionEvent.ACTION_MOVE && ballpressed){
			ballpressedevent = event;
		}
		
		if(event.getAction() == MotionEvent.ACTION_UP && ballpressed){
			ballpressedevent = event;
			float endPoints[] = Logic.computeMaxBar(ball.getMiddleX(), ball.getMiddleY(), event.getX(), event.getY());
			ball.shoot(endPoints[0], endPoints[1]);
			ballpressed = false;
			
		}
		if(event.getAction() == MotionEvent.ACTION_UP && MenuBarController.isWallButtonEnabled()){
			newLine = true; 
		}
		pressed = (event.getAction()==MotionEvent.ACTION_UP)? false:true; 
		
		detector.onTouchEvent(event);
		return true; 
	}
	
	@Override
	public boolean onDown(MotionEvent e) {
		return true;
	}
	
	

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		if(MenuBarController.isWallButtonEnabled()){
			down = e1;
			up = e2;
			newLine = true; 
			System.out.println("FLING!");
			return true;
		}
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		
	}
	

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		
		return true;
	}

	@Override
	public void onShowPress(MotionEvent e) {
	}
	
	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		System.out.println(scaledBackground.getPixel((int)e.getX(), (int)e.getY()));
		System.out.println(Color.green(scaledBackground.getPixel((int)e.getX(), (int)e.getY())));
		System.out.println(e.getX());
		System.out.println(e.getY());
		if(game.gameFinished){
			game.reset();
			Intent i = new Intent(getContext(), GameSettingsActivity.class);
			getContext().startActivity(i);
			return true;
		} 
		return true;  
	}
	
	public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
		int width = bm.getWidth();
		int height = bm.getHeight();
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;
		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the bit map
		matrix.postScale(scaleWidth, scaleHeight);
		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
		return resizedBitmap;
	}
	
	
	
	private void calcFPS() {
	  // TODO Auto-generated method stub
	  long tempTime = System.currentTimeMillis();
	  currentMS = tempTime - prevMS;
	  prevMS = tempTime;
	  second += currentMS;
	  if(second < 1000)currentFPS++;
	  else{
		   second = 0;
		   oldFPS = currentFPS;
		   currentFPS = 0;
	  }
	  dt+=currentMS;
	 }
	
	public void drawFPS(int fps, int posx, int posy, Canvas c){
	  Paint textPaint = new Paint();
	  textPaint.setColor(Color.YELLOW);
	  textPaint.setStyle(Paint.Style.FILL);
	  textPaint.setTextSize(10);
	  c.drawText("FPS: " + fps + "", posx, posy, textPaint);
	}
	
	public static void reset(){
		up = null;
		down = null;
		ballpressed = false;
		pressed = false;
	}
	
	public void showPlayerTurn(Canvas c){
		Paint p = new Paint();
		p.setColor(Color.GREEN);
		p.setTextSize(15);
		if(game.gameFinished){
			c.drawText("Tap to play new game ",(c.getWidth()/7), c.getHeight()/20, p);
		}
		else{
			c.drawText("Turn: " + game.getCurrentPlayer().toString()+ ", shot "+ (game.getCurrentPlayer().getShots()+1),(c.getWidth()/7), c.getHeight()/20, p);
		}
	}
	
	
	public static void clearWalls(){
		lineSegs.clear();
		lineCoords.clear();
	} 
	
	public static void removeLastWall(){
		if(!lineCoords.isEmpty())lineCoords.remove(lineCoords.size()-1);
		if(!lineSegs.isEmpty())lineSegs.remove(lineSegs.size()-1);
	}
	
	public static void setUpandDown(){
		if(up!=null && down!=null){
			up.setLocation(-10001, -10001);
			down.setLocation(-10001, -10001);
		}
		
	}
	
	public static MotionEvent getUp(){
		return up;
	}
	
	public static MotionEvent getDown(){
		return down;
	}

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		if (event.getPropertyName().equals("endmap")) {
			System.out.println("propertychange");
			background = BitmapFactory.decodeResource(getResources(), game.getCurrentMap().getImage());
			first = true;
			scaledBackground = getResizedBitmap(background, canvas.getHeight(), canvas.getWidth());
			System.out.println("har byttet map og ny spiller er: " + game.getCurrentPlayer());
			System.out.println("hans ballposisjon er: "+ game.getCurrentPlayer().getBall().getPosX()+","+game.getCurrentPlayer().getBall().getPosY());
		} 
		
	}
	
	
	
}	 
	

